-- 操作系统目录分隔符（Windows为"\"，其他系统为"/"）
local Sep = package.config:sub(1,1)

-- 工具函数：获取文件路径的目录部分
local function Dirname(str)
    return (str:gsub("[^"..Sep.."]*$", ""))
end

-- 工具函数：获取基础文件名（带扩展名）
local function Basename(str)
    return str:match("^.*" .. Sep .. "(.+)$") or str
end

-- 工具函数：移除文件扩展名
local function RemoveExtension(str)
    return str:gsub("%.([^.]*)$", "")
end

-- 工具函数：创建消息对话框
local function MsgDialog(title, msg)
    local dlg = Dialog(title)
    dlg:label{id = "msg", text = msg}
    dlg:newrow()
    dlg:button{id = "close", text = "关闭", onclick = function() dlg:close() end}
    return dlg
end

-- 增强版蛇形命名转换（处理特殊字符）
local function ToSnakeCase(str)
    return str:lower()
        :gsub("([a-z])([A-Z])", "%1_%2")    -- 驼峰转下划线
        :gsub("[%s%-]+", "_")                -- 空格/连字符转下划线
        :gsub("[^%w_]", "")                  -- 移除非字母数字字符
        :gsub("_+", "_")                     -- 合并连续下划线
        :gsub("^_*", "")                     -- 去除开头下划线
        :gsub("_*$", "")                     -- 去除结尾下划线
end

-- 导出图层函数
local function ExportLayer(sprite, layer, filename, cel)
    local layerFilename = filename:gsub("{layername}", ToSnakeCase(layer.name))
    local dir = Dirname(layerFilename)
    
    -- 自动创建目录（如果需要）
    if dir ~= "" then
        app.fs.makeDirectory(dir)  -- 仅在目录不存在时创建
    end
    
    -- 创建临时图像并绘制内容
    local img = Image(sprite.width, sprite.height)
    img:drawImage(cel.image, cel.position)
    
    -- 保存文件
    img:saveAs(layerFilename)
    return true
end

-- 主程序开始 --
local sprite = app.activeSprite
if not sprite then
    MsgDialog("错误", "没有打开的精灵文件"):show()
    return 1
end

-- 验证文件已保存
if not sprite.filename or sprite.filename == "" then
    MsgDialog("错误", "请先保存精灵文件"):show()
    return 1
end

-- 获取用户选择的帧
local selectedFrames = app.range.frames
if not selectedFrames or #selectedFrames == 0 then
    MsgDialog("错误", "请在时间轴上选择至少一帧"):show()
    return 1
end

-- 准备路径组件 ----------------------------------------------------------
local base_name = ToSnakeCase(RemoveExtension(Basename(sprite.filename)))
local output_path = Dirname(sprite.filename)  -- 关键修改：直接使用工程目录
------------------------------------------------------------------------

-- 初始化统计器
local successCount = 0
local failCount = 0
local failedLayers = {}

-- 存储原始可见状态
local origVisibility = {}
for _, layer in ipairs(sprite.layers) do
    origVisibility[layer] = layer.isVisible
end

-- 处理导出 --------------------------------------------------------------
for _, layer in ipairs(sprite.layers) do
    if layer.isVisible and layer.isImage then
        local cel = layer:cel(selectedFrames[1])
        
        if cel and cel.image then
            -- 构建完整路径（直接使用工程目录）
            local filename = output_path 
                .. base_name 
                .. "_" 
                .. ToSnakeCase(layer.name) 
                .. ".png"
            
            local status, err = pcall(function()
                ExportLayer(sprite, layer, filename, cel)
            end)
            
            -- 更新统计
            if status then
                successCount = successCount + 1
            else
                failCount = failCount + 1
                table.insert(failedLayers, layer.name)
                print("导出失败：" .. layer.name .. " - " .. err)
            end
        end
    end
end

-- 恢复可见状态
for layer, visible in pairs(origVisibility) do
    layer.isVisible = visible
end

-- 构建结果消息
local resultMsg
if failCount == 0 then
    resultMsg = string.format("成功导出 %d 个图层\n%s", 
        successCount, 
        output_path)
else
    resultMsg = string.format(
        "导出结果：\n成功：%d\n失败：%d\n路径：%s\n失败列表：%s",
        successCount,
        failCount,
        output_path,
        table.concat(failedLayers, ", ")
    )
end

-- 显示结果对话框
MsgDialog(
    failCount == 0 and "导出成功" or "部分失败",
    resultMsg
):show()

return 0